import { ArrowUpOutlined, EllipsisOutlined, LeftOutlined, SendOutlined } from "@ant-design/icons";
import Popup from "../../components/Popup";
import Message, { MessageType } from "../../components/Message";
import React, { ReactNode, useContext, useEffect, useRef, useState } from "react";
import { debounce } from 'lodash';
import dayjs from "dayjs";
import { RoomType } from "../../components/Room";
import { FriendType, MemberType } from "../../components/Member";
import { MemberContext } from "../../contexts/Member";
import { mergeFriendMessage, mergeRoomMessage } from "../../plugins/message";

export default function Chat({open = false, title, room, friend, onClose}: {
    open: boolean;
    title: ReactNode;
    room?: RoomType;
    friend?: FriendType;
    onClose: () => void;
}) {
    const isinit = useRef<boolean>(true);
    const [scrollable, setScrollable] = useState(true);
    // const [initinalized, setInitinalized] = useState(false);
    const [text, setText] = useState('');
    const container = useRef<HTMLDivElement>(null);
    const { setRooms, setFriends, member } = useContext(MemberContext);

    const onSend = () => {
        const content = text.trim();
        if(content.length <= 0) {
            return;
        }
        let message = {
            id: Math.random(),
            senderId: member?.id as number,
            chatTypeId: 'room',
            receiverId: 0,
            chatId: 0,
            messageTypeId: 'text',
            content: text,
            member: member as MemberType,
            status: 1,
            createdAt: dayjs().format('YYYY-MM-DD HH:mm:ss')
        };
        if(room) {
            message = {...message, receiverId: room.id, chatId: room.id};
            setRooms((rooms) => {
                return mergeRoomMessage(message, rooms, true);
            });
        }
        if(friend) {
            message = {...message, chatTypeId: 'person', receiverId: friend.id, chatId: friend.chatId};
            setFriends((friends) => {
                return mergeFriendMessage(message, friends, true);
            });
        }
        setText('');
        window?.socket?.emit('message', message);
    }
    const scrollBottom = () => {
        if(container?.current && scrollable) {
            container.current.scrollTop = container.current.scrollHeight;
        }
    };
    useEffect(() => {
        if(scrollable) {
            scrollBottom();
        }
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [room, friend]);

    useEffect(() => {
        scrollBottom();
        if(!isinit?.current) {
            if(friend && friend.unread) {
                setFriends((friends) => {
                    return friends.map((item) => {
                        if(item.chatId === friend?.chatId) {
                            return {...item, unread: 0};
                        }
                        return item;
                    });
                });
            }
            if(room && room.unread) {
                setRooms((rooms) => {
                    return rooms.map((item) => {
                        if(item.id === room?.id) {
                            return {...item, unread: 0};
                        }
                        return item;
                    });
                });
            }
        }
        if(open) {
            isinit.current = false;
        }
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [open]);

    const onSetScrollable = debounce(() => {
        if(!container?.current) {
            return;
        }
        if(container.current?.scrollHeight - container.current?.scrollTop === container.current?.clientHeight) {
            setScrollable(true);
        }
        else {
            setScrollable(false);
        }
    }, 80);

    useEffect(() => {
        if(container?.current) {
            container.current.addEventListener('scroll', onSetScrollable);
        }
        return () => {
            // eslint-disable-next-line react-hooks/exhaustive-deps
            container.current?.removeEventListener('scroll', onSetScrollable);
        };
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);


    let stayDate = '';
    const totalMessages = [...((room ? room?.messages : friend?.messages) || [])];
    const messages: Array<MessageType> | undefined = totalMessages.slice(-50);
    return <Popup open={open} closeable={false}>
        <div className="flex flex-col w-screen h-screen">
            <div className="relative h-12 flex items-center justify-center border-b">
                <div className="line-clamp-1 w-4/5 text-center">{title}</div>
                <div className="absolute right-4 text-xl h-12 flex items-center">
                    <EllipsisOutlined />
                </div>
                <div className="absolute left-4 text-xl h-12 flex items-center" onClick={onClose}>
                    <LeftOutlined />
                </div>
            </div>
            <div ref={container} className="h-[calc(100vh-48px-64px)] overflow-y-auto p-4 flex flex-col gap-6">
                {
                    totalMessages.length > 50
                        ? <div className="flex gap-2 justify-center items-center text-gray-500 text-sm">
                            <div><ArrowUpOutlined /></div>
                            <div>上划查看更多</div>
                        </div>
                        : <></>
                }
                {
                    (messages || []).map(
                        (message) => {
                            const currentDate = dayjs(message.createdAt).format('YYYY-MM-DD');
                            let dateRender = <></>;
                            if(currentDate !== stayDate) {
                                dateRender = <><div className="text-gray-500 text-xs text-center">{currentDate}</div></>;
                                stayDate = currentDate;
                            }
                            return <React.Fragment key={message.id}>
                                {dateRender}
                                <Message message={message} />
                            </React.Fragment>;
                        }
                    )
                }
            </div>
            <div className="h-16 p-4 flex items-center gap-4 border-t">
                <input className="border rounded flex-1 h-10 px-2 bg-gray-50" value={text} onChange={(e) => setText(e.target.value)} />
                <div className="
                        flex justify-center items-center w-20 h-10 rounded bg-gradient-to-r from-green-500 to-emerald-500 text-white text-xl
                    "
                    onClick={onSend}
                >
                    <SendOutlined />
                </div>
            </div>
        </div>
    </Popup>
}